home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / DEMO_VGA / FRSTM1.LZH / FRSTM.C < prev    next >
C/C++ Source or Header  |  1989-03-27  |  16KB  |  588 lines

  1. #include <graph.h>
  2. #include <dos.h>
  3. #include <conio.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <malloc.h>
  7. #include <math.h>
  8. #include <string.h>
  9. #include <time.h>
  10. #include "xbit.h"
  11. #include "chkpoint.h"
  12.  
  13. int VgaWonder = 0, ATIProduct = 1;
  14.  
  15. struct _COMPLEX {
  16.    double i, j;
  17. };
  18.  
  19. unsigned int Iterations, LineColor = 200;
  20. unsigned char far *ColorLog;
  21.  
  22. void savetodisk(char *filename, int xdots, int ydots, int colors);
  23. struct _COLOR_GUNS GIFColorTable[256];
  24.  
  25. struct _MALSET {
  26.    char FileName[40], Title[80];
  27.    struct _COMPLEX Offset, Aspect;
  28.    long ltime, Current, NumPasses, PassesLeft, NumPassed;
  29.    long Hours, Minutes, Seconds;
  30.    union _FIXED32BIT AspectX, AspectY, it, jt, Creal, Cimag;
  31.    double HLength, VLength, Scale, Delta, Overlap;
  32.    int OverflowMask, SigDigits, PassMode, Colors, Direct, BPL, InSetMask;
  33.    int JuliaFlag, EndTime;
  34.    int Midx, Midy, Overflow, NumRep, Mousex, Mousey, Mult, Buttons, DefColors;
  35.    struct videoconfig Vid;
  36. };
  37. typedef struct _MALSET *MALSET;
  38.  
  39. void ClearScreen(void) {
  40.    union REGS Regs;
  41.  
  42.    if(VgaWonder) {
  43.       Regs.x.ax = 0x63;
  44.       int86(0x10, &Regs, &Regs);
  45.    }
  46.    else
  47.       _clearscreen(_GCLEARSCREEN);
  48. }
  49. void ClearScreen(void);
  50.  
  51. void MarkTimeLeft(MALSET m) {
  52.    struct tm *t;
  53.    union REGS Regs;
  54.  
  55.    Regs.h.ah = 3;
  56.    Regs.h.bh = 0;
  57.    int86(0x10, &Regs, &Regs);
  58.    printf("%02ld:%02ld:%02ld ", m->Hours, m->Minutes, m->Seconds);
  59.    t = localtime(&m->Current);
  60.  
  61.    if(m->EndTime) {
  62.       m->Seconds += t->tm_sec;
  63.       m->Minutes += m->Seconds / 60;
  64.       m->Seconds %= 60;
  65.       m->Minutes += t->tm_min;
  66.       m->Hours += m->Minutes / 60;
  67.       m->Minutes %= 60;
  68.       m->Hours += t->tm_hour;
  69.       m->Hours %= 24;
  70.    }
  71.    else {
  72.       m->Seconds = m->Current - m->ltime;
  73.       m->Hours = m->Seconds / 3600;
  74.       m->Seconds %= 3600;
  75.       m->Minutes = m->Seconds / 60;
  76.       m->Seconds %= 60;
  77.    }
  78.  
  79.    printf("%02ld:%02ld:%02ld ", m->Hours, m->Minutes, m->Seconds);
  80.    Regs.h.ah = 2;
  81.    int86(0x10, &Regs, &Regs);
  82. }
  83.  
  84. /* Add these as a global work space */
  85. unsigned int ScreenLines, PixelsPerLine, ScanLineOff = 16;
  86.  
  87. int MultiPass(MALSET m, int Initx, int Inity, int Shift) {
  88.    if(Shift != m->Mult) {
  89.       if(!MultiPass(m, Initx, Inity, Shift << 1)) {
  90.          if(!MultiPass(m, Initx + Shift, Inity + Shift, Shift << 1)) {
  91.             if(!MultiPass(m, Initx + Shift, Inity, Shift << 1))
  92.                return(MultiPass(m, Initx, Inity + Shift, Shift << 1));
  93.          }
  94.       }
  95.    }
  96.    else {
  97.       DoubleToXBit(m->Aspect.i * m->Mult, m->AspectX.C);
  98.       DoubleToXBit(-m->Aspect.j * m->Mult, m->AspectY.C);
  99.       DoubleToXBit((-m->Aspect.i * m->Midx) + m->Offset.i + 
  100.                    (m->Aspect.i * Initx), m->it.C);
  101.       DoubleToXBit((m->Aspect.j * m->Midy) + m->Offset.j - 
  102.                    (m->Aspect.j * (Inity + ScanLineOff)), m->jt.C);
  103.       time(&m->Current);
  104.       if(m->NumPassed) {
  105.          m->Seconds = m->Current - m->ltime;
  106.          m->PassesLeft = m->NumPasses - m->NumPassed;
  107.          m->Seconds = m->PassesLeft * ((m->Seconds * 0x1000) / m->NumPassed);
  108.          m->Seconds /= 0x1000;
  109.          m->Hours = m->Seconds / 3600;
  110.          m->Minutes = (m->Seconds - (m->Hours * 3600)) / 60;
  111.          m->Seconds -= (m->Hours * 3600) + (m->Minutes * 60);
  112.          MarkTimeLeft(m);
  113.       }
  114.       m->NumPassed++;
  115.  
  116. /* Fixes problem when 'm->Mult' does not divide evenly into pixel count */
  117.       ScreenLines = (m->Vid.numypixels - ScanLineOff) / m->Mult;
  118.       if(Inity < ((m->Vid.numypixels - ScanLineOff) % m->Mult))
  119.          ScreenLines++;
  120.       PixelsPerLine = m->Vid.numxpixels / m->Mult;
  121.       if(Initx < (m->Vid.numxpixels % m->Mult))
  122.          PixelsPerLine++;
  123.  
  124.       return(DrawMandelbrot(m->it.L, m->jt.L, Iterations, m->NumRep, 
  125.              m->AspectX.L, m->AspectY.L, PixelsPerLine, ScreenLines, 
  126.              m->OverflowMask, m->SigDigits, m->BPL, Initx, 
  127.              Inity + ScanLineOff, m->Mult, m->BPL * (m->Mult - 1), 
  128.              m->Mousex, m->Mousey, m, ColorLog, 
  129.              m->Buttons, m->Direct, m->InSetMask, m->JuliaFlag,
  130.              m->Creal.L, m->Cimag.L));
  131.    }
  132. }
  133.  
  134. void far MouseRoutine(struct _MALSET far *m, int x, int y, int Buttons);
  135.  
  136. void SetPalReg(int n, unsigned char Red, unsigned char Green, 
  137.                unsigned char Blue) {
  138.    union REGS Regs;
  139.  
  140.    Regs.h.ah = 0x10;
  141.    Regs.h.al = 0x10;
  142.    GIFColorTable[n].Red = (Regs.h.dh = Red) << 2;
  143.    GIFColorTable[n].Blue = (Regs.h.cl = Blue) << 2;
  144.    GIFColorTable[n].Green = (Regs.h.ch = Green) << 2;
  145.    Regs.x.bx = n;
  146.    int86(0x10, &Regs, &Regs);
  147. }
  148.  
  149. void SetPalette(MALSET m) {
  150.    union REGS Regs;
  151.    double RedAngle, GreenAngle, BlueAngle, TwoPi, TwoThirdsPi, Fudge;
  152.    unsigned char Red, Green, Blue;
  153.    unsigned n;
  154.  
  155.    if(!m->DefColors) {
  156.       for(n = 0; n < 256; n++) {
  157.          Regs.h.ah = 0x10;
  158.          Regs.h.al = 0x15;
  159.          Regs.x.bx = n;
  160.          int86(0x10, &Regs, &Regs);
  161.          GIFColorTable[n].Red = Regs.h.dh << 2;
  162.          GIFColorTable[n].Green = Regs.h.ch << 2;
  163.          GIFColorTable[n].Blue = Regs.h.cl << 2;
  164.       }
  165.       return;
  166.    }
  167.    ClearScreen();
  168.    _settextcolor(200);
  169.    printf("Setting palette");   
  170.    TwoPi = asin(1.0) * 4.0;
  171.    TwoThirdsPi = TwoPi / 3.0;
  172.    Fudge = asin(1.0) / 2.5;
  173.    for(n = 1; n < 256; n++) {
  174.       BlueAngle = (TwoPi / (255.0 / m->Overlap)) * (float)((long)n) + Fudge;
  175.       GreenAngle = BlueAngle + TwoThirdsPi;
  176.       RedAngle = GreenAngle + TwoThirdsPi;
  177.  
  178.       Red = (unsigned char)((long)(((cos(RedAngle) + 1.0) * 31.5) + 0.5));
  179.       Blue = (unsigned char)((long)(((cos(BlueAngle) + 1.0) * 31.5) + 0.5));
  180.       Green = (unsigned char)((long)(((cos(GreenAngle) + 1.0) * 31.5) + 0.5));
  181.       SetPalReg(n, Red, Green, Blue);
  182.    }
  183. }
  184.  
  185. void ClipLine(struct _MALSET far *m, int x1, int y1, int x2, int y2) {
  186.    if((x1 < m->Vid.numxpixels) && (y1 < m->Vid.numypixels) &&
  187.       (x2 >= 0) && (y2 >= 0)) {
  188.       if(x1 < 0)
  189.          x1 = 0;
  190.       if(y1 < 0)
  191.          y1 = 0;
  192.       if(x2 >= m->Vid.numxpixels)
  193.          x2 = m->Vid.numxpixels;
  194.       if(y2 >= m->Vid.numypixels)
  195.          y2 = m->Vid.numypixels;
  196.       if(x1 == x2)
  197.          ATIxorLine(x1, y1, m->Vid.numxpixels, y2 - y1, m->Vid.numxpixels);
  198.       else
  199.          ATIxorLine(x1, y1, 1,                 x2 - x1, m->Vid.numxpixels);
  200.    }
  201. }
  202.  
  203. void MouseCursor(struct _MALSET far *m, int x, int y) {
  204.    ClipLine(m, x - 5, y, x + 6, y);
  205.    ClipLine(m, x, y - 5, x, y + 6);
  206. }
  207.  
  208. void far MouseRoutine(struct _MALSET far *m, int x, int y, int Buttons) {
  209.    double i, j;
  210.    clock_t tick;
  211.    union REGS Regs, Pos;
  212.  
  213.    Pos.h.ah = 3;
  214.    Pos.h.bh = 0;
  215.    int86(0x10, &Pos, &Pos);
  216.    if(m->Mousex != -1)
  217.       MouseCursor(m, m->Mousex, m->Mousey);
  218.    m->Mousex = x;
  219.    m->Mousey = y;
  220.    i = (m->Aspect.i * (x - m->Midx)) + m->Offset.i;
  221.    j = (m->Aspect.j * (m->Midy - y)) + m->Offset.j;
  222.    Regs.h.ah = 2;
  223.    Regs.h.bh = 0;
  224.    if(VgaWonder) {
  225.       Regs.h.dh = 0;
  226.       Regs.h.dl = 40;
  227.    }
  228.    else {
  229.       Regs.h.dh = 1;
  230.       Regs.h.dl = 0;
  231.    }
  232.    int86(0x10, &Regs, &Regs);
  233.    printf("i = %+01.8f, j = %+01.8f", i, j, 
  234.           m->Scale * m->Delta);
  235.    Pos.h.ah = 2;
  236.    int86(0x10, &Pos, &Pos);
  237.    MouseCursor(m, x, y);
  238.    tick = clock();
  239.    while(clock() == tick);
  240. }
  241.  
  242. void SetupMouse(MALSET m) {
  243.    union REGS Regs;
  244.  
  245.    Regs.x.ax = 0;
  246.    int86(0x33, &Regs, &Regs);
  247.  
  248.    Regs.x.ax = 4;
  249.    Regs.x.cx = m->Midx;
  250.    Regs.x.dx = m->Midy;
  251.    int86(0x33, &Regs, &Regs);
  252.  
  253.    Regs.x.ax = 7;
  254.    Regs.x.cx = 0;
  255.    Regs.x.dx = m->Vid.numxpixels - 1;
  256.    int86(0x33, &Regs, &Regs);
  257.  
  258.    Regs.x.ax = 8;
  259.    Regs.x.cx = 0;
  260.    Regs.x.dx = m->Vid.numypixels - 1;
  261. }
  262.  
  263. void Malset(MALSET m) {
  264.    char Str[140];
  265.    struct tm *t;
  266.    int Done = 0, n;
  267.    union REGS Regs;
  268.  
  269.    m->Mult = (1 << (m->PassMode - 1));
  270.    m->Mousex = -1;
  271.    m->Buttons = 0;
  272.    m->Delta = 1.0;
  273.  
  274.    SetPalette(m);
  275.  
  276.    m->NumPassed = 0L;
  277.    m->NumPasses = (long)m->Mult * m->Mult;
  278.    time(&m->ltime);
  279.  
  280.    Regs.h.ah = 2;
  281.    Regs.x.dx = 0;
  282.    Regs.h.bh = 0;
  283.    int86(0x10, &Regs, &Regs);
  284.  
  285.    SetupMouse(m);
  286.    MultiPass(m, 0, 0, 1);
  287.  
  288.    t = localtime(&m->ltime);
  289.    Regs.h.ah = 2;
  290.    Regs.x.dx = 0;
  291.    Regs.h.bh = 0;
  292.    int86(0x10, &Regs, &Regs);
  293.    MouseCursor(m, m->Mousex, m->Mousey);
  294. /* printf("%80s", " ");
  295.  
  296.    Regs.h.ah = 2;
  297.    Regs.x.dx = 0;
  298.    Regs.h.bh = 0;
  299.    int86(0x10, &Regs, &Regs);
  300.    if(VgaWonder)
  301.       printf("%s, %d/%d/%d", m->Title, t->tm_mon + 1, t->tm_mday, t->tm_year);
  302.    else {
  303.       printf("%s\n", m->Title);
  304.       printf("%d/%d/%d", t->tm_mon + 1, t->tm_mday, t->tm_year);
  305.    } */
  306. }
  307.  
  308. void PrintTitle(void) {
  309.    _clearscreen(_GCLEARSCREEN);
  310.    printf("Fire Storm Drawing Program - Version 1.0\n");
  311.    printf("   -by Mark C. Peterson\n");
  312.    printf("    CompuServe [70441,3353]\n");
  313.    printf("Program resides in the public domain.\n\n");
  314. }
  315. void PrintTitle(void);
  316.  
  317. char *Get(char *Response) {
  318.    union REGS Regs;
  319.  
  320.    Regs.h.ah = 3;
  321.    Regs.h.bh = 0;
  322.    int86(0x10, &Regs, &Regs);
  323.    gets(Response);
  324.    Regs.h.ah = 2;
  325.    int86(0x10, &Regs, &Regs);
  326.    return(Response);
  327. }
  328.  
  329. void GetDefaults(MALSET m) {
  330.    double d;
  331.    char Response[200];
  332.  
  333.    SetXBit(4, 2);
  334.    m->HLength = 10.0;
  335.    m->VLength = 7.0;
  336.  
  337.    printf("Exit instructions:\n");
  338.    printf("   Ctrl-C during quiry.\n");
  339.    printf("   'Esc' three times while drawing.\n\n");
  340.  
  341.    if(VgaWonder) {
  342.       printf("Use 800x600x256 mode ('y' default)? ");
  343.       Get(Response);
  344.       if((Response[0] == 'n') || (Response[0] == 'N'))
  345.          VgaWonder = 0;
  346.       else
  347.          printf("Yes");
  348.       printf("\n");
  349.    }
  350.  
  351.    printf("Significant binary digits (1 -> 29, 13 default)? ");
  352.    m->SigDigits = atoi(Get(Response));
  353.    if(!m->SigDigits)
  354.       m->SigDigits = 13;
  355.    if(m->SigDigits < 1)
  356.       m->SigDigits = 1;
  357.    if(m->SigDigits > 29)
  358.       m->SigDigits = 29;
  359.    printf("%d      \n", m->SigDigits);
  360.  
  361.    printf("Pattern repetition threshold (1 -> 65535, 2 default)? ");
  362.    if(!(m->NumRep = atoi(Get(Response))))
  363.       m->NumRep = 2;
  364.    printf("%d       \n", m->NumRep);
  365.  
  366.    printf("Iteration threshold (1 -> 65535, 500 default)? ");
  367.    if(!(Iterations = atoi(Get(Response))))
  368.       Iterations = 500;
  369.    printf("%u      \n", Iterations);
  370.  
  371.    printf("Scale (0.45 maximum and default)? ");
  372.    m->Scale = atof(Get(Response));
  373.    if((m->Scale > 0.45) || (m->Scale <= 0.0))
  374.       m->Scale = 0.45;
  375.    printf("%01.8f      \n", m->Scale);
  376.  
  377.    printf("i Offset (0.0 default)? ");
  378.    m->Offset.i = atof(Get(Response));
  379.    printf("%01.8f      \n", m->Offset.i);
  380.  
  381.    printf("j Offset (0.0 default)? ");
  382.    m->Offset.j = atof(Get(Response));
  383.    printf("%01.8f      \n", m->Offset.j);
  384.  
  385.    printf("Mandelbrot set ('y' default)? ");
  386.    Get(Response);
  387.    if((Response[0] == 'n') || (Response[0] == 'N')) {
  388.       m->JuliaFlag = 1;
  389.       printf("\nJulia i? ");
  390.       d = atof(Get(Response));
  391.       DoubleToXBit(d, m->Creal.C);
  392.       d = XBitToDouble(m->Creal.C);
  393.       printf("%01.8f       \nJulia j? ", d);
  394.       d = atof(Get(Response));
  395.       DoubleToXBit(d, m->Cimag.C);
  396.       d = XBitToDouble(m->Cimag.C);
  397.       printf("%01.8f       ", d);
  398.    }
  399.    else {
  400.       m->JuliaFlag = 0;
  401.       printf("Yes    ");
  402.    }
  403.    printf("\n");
  404.  
  405.    printf("Display overflows ('y' default)? ");
  406.    Get(Response);
  407.    if((Response[0] == 'n') || (Response[0] == 'N'))
  408.       m->OverflowMask = 0;
  409.    else {
  410.       m->OverflowMask = 0xff;
  411.       m->Colors = 256;
  412.       printf("Yes\nSmooth chromatic gradient ('y' default)? ");
  413.       Get(Response);
  414.       if((Response[0] == 'n') || (Response[0] == 'N')) {
  415.          m->DefColors = 0;
  416.          printf("No  \n");
  417.       }
  418.       else {
  419.          m->DefColors = 1;
  420.          printf("Yes\n");
  421.          printf("Number of scale color overlaps (1.0 default)? ");
  422.          m->Overlap = atof(Get(Response));
  423.          if(!m->Overlap)
  424.             m->Overlap = 1.0;
  425.          printf("%g    \n", m->Overlap);
  426.       }
  427.  
  428.       printf("Display set interior ('n' default)? ");
  429.       Get(Response);
  430.       if((Response[0] == 'y') || (Response[0] == 'Y'))
  431.          m->InSetMask = -1;
  432.       else {
  433.          m->InSetMask = 0;
  434.          printf("No");
  435.       }
  436.    }
  437.    printf("\n");
  438.  
  439.    printf("Multiple passes mode (1 -> 6, 6 default)? ");
  440.    m->PassMode = atoi(Get(Response));
  441.    if(!m->PassMode || (m->PassMode > 6))
  442.       m->PassMode = 6;
  443.    if(m->PassMode < 1)
  444.       m->PassMode = 1;
  445.    printf("%d\n", m->PassMode);
  446.  
  447.    printf("Name of GIF file ('frstm.gif' default)? ");
  448.    if(!strcpy(m->FileName, Get(Response))[0])
  449.       strcpy(m->FileName, "frstm.gif");
  450.    printf("%s         \n", m->FileName);
  451.  
  452.    printf("Title (Coord info default)? ");
  453.    strcpy(m->Title, Get(Response));
  454.    if(!m->Title[0])
  455.       if(m->JuliaFlag)
  456.          sprintf(m->Title, "%1.8f + %1.8f", 
  457.                  XBitToDouble(m->Creal.C), XBitToDouble(m->Cimag.C));
  458.       else
  459.          sprintf(m->Title, "%1.8f + %1.8f, %1.6f", m->Offset.i,
  460.                  m->Offset.j, m->Scale);
  461.    printf("%s         \n", m->Title);
  462.  
  463.    printf("Time display (1 = Time spent, 2 = Ending time)? ");
  464.    m->EndTime = atoi(Get(Response)) & 1;
  465.  
  466.    ClearScreen();
  467. }
  468.  
  469. void SetVideo(MALSET m) {
  470.    union REGS Regs;
  471.  
  472.    if(VgaWonder) {
  473.       Regs.x.ax = 0x63;
  474.       int86(0x10, &Regs, &Regs);
  475.       m->Vid.numxpixels = 800;
  476.       m->Vid.numypixels = 600;
  477.    }
  478.    else {
  479.       if(!_setvideomode(_MRES256COLOR)) {
  480.          printf("Sorry, VGA required for this version.\n\n");
  481.          exit(1);
  482.       }
  483.       _getvideoconfig(&m->Vid);
  484.    }
  485. }
  486.  
  487. void ChkForVgaWonder(void) {
  488.    char far *ATISigLoc = (char far *)0xc0000031;
  489.    char far *VgaWonderLoc = (char far *)0xc0000040;
  490.    static char ATIStr[] = "761295520";
  491.    static char VgaWonderStr[] = "31";
  492.    unsigned n;
  493.  
  494.    for(n = 0; ATIStr[n]; n++) {
  495.       if(ATIStr[n] != ATISigLoc[n])
  496.          ATIProduct = 0;
  497.    }
  498.    if(ATIProduct) {
  499.       for(n = 0; VgaWonderStr[n]; n++) {
  500.          if(VgaWonderStr[n] != VgaWonderLoc[n])
  501.             return;
  502.       }
  503.       VgaWonder = GetATIConfig();
  504.       VgaWonder = (VgaWonder >= 0x25);
  505.    }
  506. }
  507. void ChkForVgaWonder(void);
  508.  
  509. void main(void) {
  510.    FILE *LogFile;
  511.    char LogFileName[20];
  512.    double LogIter, LogColor;
  513.    MALSET m;
  514.    union REGS Regs;
  515.    unsigned n, Done = 0;
  516.  
  517.    m = calloc(1, sizeof(struct _MALSET));
  518.  
  519.    ChkForVgaWonder();   
  520.  
  521.    PrintTitle();
  522.    SetVideo(m);
  523.    _setvideomode(_DEFAULTMODE);
  524.    GetDefaults(m);
  525.    SetVideo(m);
  526.  
  527.    m->Direct = 1;
  528.    m->BPL = m->Vid.numxpixels;
  529.    m->Midx = m->Vid.numxpixels / 2;
  530.    m->Midy = m->Vid.numypixels / 2;
  531.  
  532.    m->Aspect.i = (m->Scale * m->HLength) / m->Vid.numxpixels;
  533.    m->Aspect.j = (m->Scale * m->VLength) / m->Vid.numypixels;
  534.    while(kbhit())
  535.       getch();
  536.  
  537.    Regs.h.ah = 2;
  538.    Regs.h.bh = 0;
  539.    Regs.x.dx = 0;
  540.    int86(0x10, &Regs, &Regs);
  541.  
  542.    ColorLog = _fmalloc(Iterations);
  543.    sprintf(LogFileName, "%u.lgt", Iterations);
  544.    if(!(LogFile = fopen(LogFileName, "rb+"))) {
  545.       printf("       Computing Color Table");
  546.       LogIter = log((double)((float)((unsigned long)(Iterations))));
  547.       for(n = 1; n < Iterations; n++) {
  548.          if(!(n % 100)) {
  549.             Regs.h.ah = 2;
  550.             Regs.h.bh = 0;
  551.             Regs.x.dx = 0;
  552.             int86(0x10, &Regs, &Regs);
  553.             printf("%u", n);
  554.          }
  555.          LogColor = log((double)((float)((unsigned long)(n)))) / LogIter;
  556.          LogColor *= (double)((float)((unsigned long)m->Colors));
  557.          ColorLog[n - 1] = (unsigned char)((unsigned long)((float)(LogColor)));
  558.       }
  559.       LogFile = fopen(LogFileName, "wb+");
  560.       for(n = 0; n < Iterations; n++)
  561.          putc(ColorLog[n], LogFile);
  562.       fclose(LogFile);
  563.    }
  564.    else {
  565.       for(n = 0; n < Iterations; n++)
  566.          ColorLog[n] = (unsigned char)getc(LogFile);
  567.       fclose(LogFile);
  568.    }
  569.  
  570.    if(!m->DefColors) {
  571.       for(n = 16; n < 256; n++)
  572.          ColorLog[n] = (unsigned char)(255 - ColorLog[n]);
  573.    }
  574.  
  575.    Malset(m);
  576.    while(kbhit())
  577.       getch();
  578.    savetodisk(m->FileName, m->Vid.numxpixels, m->Vid.numypixels, 256);
  579.    while(!Done) {
  580.       if(kbhit()) {
  581.          if(getch() == 27)
  582.             Done = 1;
  583.       }
  584.    }
  585.    _setvideomode(_DEFAULTMODE);
  586. }
  587.  
  588.